package visualization;

import graphs.XYOdorInputVOutputJGraph;

import java.awt.Dimension;

import javax.swing.JFrame;

import odor.Odor;

import structures.Network;

/**
 * Handles network runtime visualization through GUI
 * @author pedro
 *
 */
public class SingleNetworkAnalysisFrame extends JFrame implements RunsSimulation
{
	private static final long serialVersionUID = -4075931929979602126L;
	public static final int X_OFFSET = 5;
	public static final int Y_OFFSET = 50;
	private JNetwork myJNetwork;
	private final boolean SINGLE_ODOR;
	private Odor[] battery;
	private ControlWidget myControlWidget;
	private XYOdorInputVOutputJGraph outputGraph;
	
	public SingleNetworkAnalysisFrame(Network n)
	{
		SINGLE_ODOR = true;
		
		setFrameOptions();
		
		populateComponentsFromNetwork(n);
		
		initializeGraphics(n);
		
		setupControlWidget();
	}
	
	public SingleNetworkAnalysisFrame(Network n, Odor i)
	{
		SINGLE_ODOR = true;
		
		setFrameOptions();
		
		populateComponentsFromNetwork(n);
		
		this.myJNetwork.setOdor(i);
		
		initializeGraphics(n);
		
		setupControlWidget();
	}
	
	public SingleNetworkAnalysisFrame(Network n, Odor[] battery)
	{
		SINGLE_ODOR = false;
		
		this.battery = battery;
		
		setFrameOptions();
		
		populateComponentsFromNetwork(n);
		
		initializeGraphics(n);
		
		setupControlWidget();
	}
	
	private void setFrameOptions()
	{
		this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		this.setResizable(false);
	}
	
	public JNetwork getJNetwork()
	{
		return this.myJNetwork;
	}
	
	/**
	 * Sets input Odor to passed var
	 * @param i - Odor input
	 */
	public void setOdor(Odor i)
	{
		myJNetwork.setOdor(i);
		myJNetwork.repaint();
	}
	
	/**
	 * Sets component size based on initialization constants
	 * @param network
	 */
	private void initializeGraphics(Network network)
	{		
		this.setSize(new Dimension(X_OFFSET+JNetwork.COL_START_X+JNetwork.COL_OFFSET*network.getNumCols(), 
				Y_OFFSET+JNetwork.COL_START_Y+JNetwork.GRANULE_RADIUS*myJNetwork.getNumCols()));
		this.setTitle("Main Simulation");
		this.repaint();
	}
	
	private void setupControlWidget()
	{
		if (battery == null)
		{
			myControlWidget = new ControlWidget(this);
			myControlWidget.setVisible(true);
		}
		else
		{
			myControlWidget = new ControlWidget(this, battery);
			myControlWidget.setVisible(true);
		}
	}
	
	/**
	 * Adds all embedded Network components to JNetwork
	 * @param network - Network to be embedded
	 */
	private void populateComponentsFromNetwork(Network network)
	{
		myJNetwork = new JNetwork(network);
		myJNetwork.setNumColumn(network.getNumCols());
		this.getContentPane().add(myJNetwork);	
		
		this.validate();
	}
	
	/**
	 * Runs fire() command on embedded JNetwork
	 * Validates + Repaints components in Frame aftewards
	 */
	public void runSimulation(Object data)
	{
		if (SINGLE_ODOR)
		{
			myJNetwork.fire(myJNetwork.getInput());
			
			outputGraph = null;
			outputGraph = new XYOdorInputVOutputJGraph(myJNetwork.getInput(), myJNetwork.getOutput());
		}
		else
		{
			myJNetwork.fire(myControlWidget.getSelectedOdor());
			
			if (outputGraph == null)
				outputGraph = new XYOdorInputVOutputJGraph(myControlWidget.getSelectedOdor(), myJNetwork.getOutput());
			else
			{
				outputGraph.addXYSeries(myControlWidget.getSelectedOdor(), myJNetwork.getOutput());
				outputGraph.setVisible(true);
			}
		}
		
		
		this.validate();
		this.repaint();
		
		
		
		myJNetwork.resetGranules();
	}
	
}
